function [ elapsedTimeGf, elapsedTimeGm ] = main(dataFile, userFtPt )

dbstop if error

% Reuse minimal graph
% Use full graph each time 
REUSE = 1;

if nargin==0
    [filename, pathname] = uigetfile('*.mat', 'Select the mat file of the source mesh');
    dataFile=strcat(pathname, filename);
end

load (dataFile);

% Full signature
%vSignature = vSignatureForIndex(vSignatureFull, 2);
% Vasyl
vSignatureModif = vSignature(:,4:16);
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% User parameters for the matching                    %
% They should be carrefully choosen for each matching %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
global matchVThreshold;     % threshold for the vertex matching
matchVThreshold=0.95;        % 0.95
global edgeRatioThreshold;  % ratio threshold for the edge matching
edgeRatioThreshold=0.15;     % ratio
global m_DescriptorSigma;
m_DescriptorSigma=0.9;      % 0.9

global edgeDelta;
global maxGeoDist;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Compute the smallest edge distance %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[nbTri,~]=size(triangles);
minEdgeL=norm(vertices(triangles(1,1),:)-vertices(triangles(1,2),:));
for i=1:nbTri
    l(1)=norm(vertices(triangles(i,2),:)-vertices(triangles(i,1),:));
    l(2)=norm(vertices(triangles(i,3),:)-vertices(triangles(i,2),:));
    l(3)=norm(vertices(triangles(i,1),:)-vertices(triangles(i,3),:));
    for j=1:3
        if l(j)<minEdgeL
            minEdgeL=l(j);
        end
    end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Extraction of the main feature points                 %
% To select a vertex in 3DS Max: select $.verts[#{179}] %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%disp('Full graph..');
tic; % full graph
[ fullGraphV ] = ExtractFtPts( vSignatureModif, triangles  );
elapsedTimeGf = toc; % full graph
save('../fullGraphV.txt','fullGraphV','-ascii');
%save('ftPts.txt','ftPts','-ascii');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Compute the average edge length %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
maxEdgeDelta=0;
avrEdgeDelta=0;
for i=1:nbTri
    tmp=vertices(triangles(i,1),:)-vertices(triangles(i,2),:);
    l=sqrt(tmp*tmp');
    avrEdgeDelta=avrEdgeDelta+l;
    if l>maxEdgeDelta
        maxEdgeDelta=l;
    end
    tmp=vertices(triangles(i,2),:)-vertices(triangles(i,3),:);
    l=sqrt(tmp*tmp');
    avrEdgeDelta=avrEdgeDelta+l;
    if l>maxEdgeDelta
        maxEdgeDelta=l;
    end
    tmp=vertices(triangles(i,3),:)-vertices(triangles(i,1),:);
    l=sqrt(tmp*tmp');
    avrEdgeDelta=avrEdgeDelta+l;
    if l>maxEdgeDelta
        maxEdgeDelta=l;
    end
end
avrEdgeDelta=avrEdgeDelta/(nbTri*3);
edgeDelta=avrEdgeDelta;

% We assume the existance of distanceMtr
fullGraphVDistanceMtr=distanceMtr(fullGraphV,:);
userFtPtDistanceMtr=distanceMtr(userFtPt,:);
maxGeoDist=max(max(distanceMtr));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Compute the surface area per vertex %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[ vertSurfArea ] = CompSurfAreaPerVert( vertices, triangles );



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% If the number of ftPt is more than one, we take the minGraph has the fullGraph %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if numel(userFtPt)>1
    minGraphV=fullGraphV;
    minGraphVDistanceMtr=fullGraphVDistanceMtr;
    
    %%%%%%%%%%%%%%%%%%%%%
    % Save all the data %
    %%%%%%%%%%%%%%%%%%%%%
    srcMinGraphV=minGraphV;
    srcMinGraphVSignature=vSignatureModif(minGraphV,:);              % Vertex signature
    srcMinGraphFullDistanceMtr=minGraphVDistanceMtr;            % Geodesic distance of the extended min graph to all other vertices
    srcUserFtPtID=userFtPt;
    srcVertSurfArea=vertSurfArea;
    srcInitMinGraphV=cell(numel(userFtPt),1);
    for i=1:numel(userFtPt)
        userFtPtDistanceMtr=distanceMtr(userFtPt(i),:);
        srcInitMinGraphV{i}=CompInitialMinGraph(fullGraphV,userFtPt(i),fullGraphVDistanceMtr,userFtPtDistanceMtr);
    end

    % Binary saving
    save('dataForTrg','srcMinGraphV','srcMinGraphVSignature',...
        'srcMinGraphFullDistanceMtr','srcUserFtPtID','srcInitMinGraphV','srcVertSurfArea', 'userFtPt');
    return;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Compute the initial minimal graph %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%disp('Min graph');
tic; % min graph

if(REUSE)
    minGraphV = fullGraphV;
else
    minGraphV = CompInitialMinGraph(fullGraphV,userFtPt,fullGraphVDistanceMtr,userFtPtDistanceMtr);
end % if

nMV = size(minGraphV, 1);
minGraphE = zeros(nMV, 2);
for vi = 1 : nMV
minGraphE(vi, 1) = userFtPt;
end % for
minGraphE(:,2) = minGraphV;

minGraphVwithLandmark = zeros(nMV + 1, 1);
minGraphVwithLandmark(1, 1) = userFtPt;
minGraphVwithLandmark(2:nMV+1, 1) = minGraphV;
save('../minGraphVwithLandmark.txt','minGraphVwithLandmark','-ascii');
save('../minGraphE.txt','minGraphE','-ascii');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Grow the minimal graph to remove ambiguity in the graph matching %
% The algorithm uses the adjacency matrix                          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
minGraphV = ExtendMinGraph(vSignatureModif,...
                         minGraphV,fullGraphV,fullGraphVDistanceMtr,...
                         userFtPt,vertSurfArea);
elapsedTimeGm = toc; % min graph                     
                     
end % main

